'''BeautifulSoup 基本使用'''
'''用于解析 HTML文档内容的第三方库'''
from bs4 import BeautifulSoup as bs

'''初始化 html内容'''
html = '''
<html>
    <head>
        <title>这是标题The Dormouse's story</title>
    </head>
<body>
    <div>
        <p class="">
            <a href="#">百度1下，就知道</a>
            <a href="#">百度2下，就知道</a>
            <a href="#">百度3下，就知道</a>
        </p>
    </div>
    <p class="title titile1" style="">1234567<b>The Dormouse's story</b></p>
    <p class="story">Once upon a time there were three little sisters; and their names were
    <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
    <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
    <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
    and they lived at the bottom of a well.</p>
    <p class="story title">...</p>
    <ul>
        <li data-abc='abc' class="item item1">第1项目</li>
        <li class="item item1 item2">第2项目</li>
        <li data-123='123' class="item item1 item2">第3项目</li>
        <li class="item item2 item1">第4项目</li>
        <li data-abc='abcd' class="item">第5项目sisters</li>
        <li class="item">第6项目</li>
        <li class="item">第7项目</li>
        <li class="item">第8项目</li>
        <li class="item">第9项目sisters</li>
        <li class="item">第10项目</li>
    </ul>
</body>
</html>
'''

'''初始化 bs4的对象'''
soup = bs(html, 'html.parser')
print(soup.head.string)
'''通过 .prettify() 可以得到一个整理之后规范的标准的HTML文档'''
print(soup.prettify())

'''实例化后的 BeautifulSoup 对象将 HTML文档转换成一个 虚拟DOM树
树的分支点称之为 节点 ，每一个节点都是一个Python对象
一共有4种对象
'''
'''1.Tag 标签对象
Tag 与HTML 原生文档中的 标签名字相同  tag == 标签
'''
print(soup.title)
print(soup.p)
print(soup.a)
print(type(soup.a))

'''首先通过BS类的实例 soup.tag的形式 选取 对应的标签的名称
只能选中对应标签中的 第一个
Tag 中重要的属性有2个  name, attributes
'''
'''Name 每一个Tag都有自己的名字，通过 .name 进行获取'''
print(soup.p.name)
'''bs也可以通过 name 修改对应的 name'''
# soup.p.name = 'div'
# print(soup.prettify())

'''Attributes 属性 对等的是 HTML元素的 行内属性 比如 id class '''
print(soup.p['class'])
print(soup.p.attrs)
print(soup.a.attrs)

'''2.NavigableString 获取标签的内容'''
print(soup.title.string)
print(soup.p.string)

'''3.遍历文档树'''
'''3.1字节点
通过 Tag的name 来遍历
'''
print(soup.head.title)
print(soup.p.b)
print(soup.find_all('a'))
for item in soup.find_all('li'):
    print(type(item))
    print(item.attrs)
    print(item.string)

'''3.2 .contents 和 .children
这2个属性仅包含tag 的直接子节点
'''
'''.contents 属性可以将tag的子节点以列表的方式输出'''
print(soup.html.contents)
'''.children 属性可以将tag的子节点以迭代器的方式输出'''
print(soup.html.children)
for index,child in enumerate(soup.html.children):
    print(index, child)

'''.descendants  属性可以对 tag 下所有的子孙节点进行递归遍历'''
for index,child in enumerate(soup.html.descendants):
    print(index, child)

'''3.3 .parents 父辈节点'''
print(soup.a.parents)
for item in soup.ul.parents:
    if item is None:
        print(item)
    else:
        print(item.name)

print(soup.name)
'''.parent 父节点 '''
print(soup.a.parent)

'''3.4 兄弟节点'''
'''
.next_sibling 和 .previous_sibling
都是 往下 或者往上 各找一个

.next_siblings 和 .previous_siblings
都会生成一个迭代器，分别对 遍历的方向的元素进行迭代 直到找不到为止
'''
print(repr(soup.li.next_sibling))

for item in soup.li.next_siblings:
    print('item:',repr(item))


'''4.过滤器'''
'''4.1 字符串过滤'''
print(soup.p.find_all('a'))
for index, item in enumerate(soup.div.p.find_all('a')):
    print(index, item)

'''4.2 正则表达式'''
import re
for tag in soup.find_all(re.compile("^b")):
    print(tag.name)

'''对文档中所有的文字内容进行正则比对'''
print(soup.find(text=re.compile('sisters')))
print(soup.find_all(text=re.compile('sisters')))
'''对文档中所有的属性中指定的属性进行正则'''
print(soup.find_all(href=re.compile('elsie'), id='link1', class_='sister'))

'''对特殊属性的匹配 例如 ： html5 中的新属性  data-*'''
print(soup.find_all(attrs={'data-abc': re.compile('^abc+')}))



# '''4.3 列表方式'''
# for tag in soup.find_all(['a', 'b']):
#     print(tag.name, tag.string)
#
# for tag in soup.find_all('p', 'title'):
#     print(tag.name, tag.string)
#
# for tag in soup.find_all('p', 'story', limit=1):
#     print(tag.name, tag.string)
#     for item in tag.find_all('a'):
#         print(item.name,item.string)
# '''find() 查找当前 匹配条件满足的第一个元素'''
# print(soup.find(id='link1'))
# '''id=True 表示 找到带有 id 属性的元素 并且id 的值是有效的'''
# print(soup.find(id=True))
# print(soup.find_all(id=True))
#
# '''4.4 按CSS 的属性进行过滤'''
# '''此方式是BS4 版本之后方式 引入一个关键字 class_'''
# print(soup.find_all('li', class_='item item1 item2'))
















